home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-06-24 | 8.8 KB | 292 lines | [TEXT/MPS ] |
- // Copyright © 1994-95 by Apple Computer, Inc. All rights reserved.
- // BetterFeedbackCmd.cp
-
- #ifndef __BETTERFEEDBACK__
- #include "BetterFeedback.h"
- #endif
-
- #ifndef __UMACAPPUTILITIES__
- #include <UMacAppUtilities.h>
- #endif
-
- #ifndef __UVIEW__
- #include <UView.h>
- #endif
-
- #ifndef __UWINDOW__
- #include <UWindow.h>
- #endif
-
- #ifndef __UFAILURE__
- #include <UFailure.h>
- #endif
-
- #ifndef __LOWMEM__
- #include <LowMem.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __RETRACE__
- #include <Retrace.h>
- #endif
-
- #ifndef __QUICKDRAW__
- #include <Quickdraw.h>
- #endif
-
- #ifndef __DEVICES__
- #include <Devices.h>
- #endif
-
- #ifndef __START__
- #include <Start.h>
- #endif
-
- #ifndef __TRAPS__
- #include <Traps.h>
- #endif
-
- //----------------------------------------------------------------------------------------
-
- struct QElemWithA5AndCounter
- {
- QElemWithA5AndCounter(); // Constructor
- long OldA5; // A place to store the old value of A5, since
- // when debugging the compiler trashes the value
- // of A0 for any locals in the VBL task thus making
- // the pointer to the ParamBlockRec unavailable
- long A5; // The value of A5 will be stored here to be
- // available at VBL time
- VBLTask q; // our VBL queue element
- };
-
- inline QElemWithA5AndCounter::QElemWithA5AndCounter()
- {
- OldA5 = 0;
- A5 = 0;
- }
-
- typedef QElemWithA5AndCounter* QElemWithA5AndCounterPtr;
-
- //----------------------------------------------------------------------------------------
- // Globals
-
- long gCounter; // our counter incremented in the VBL task
- short gSlot; // the slot our VBL is installed in
- QElemWithA5AndCounter gOurVBLTask; // our VBL task record
-
- //----------------------------------------------------------------------------------------
- // IncOurVBLCounter - our VBL task that increments the counter which is tested in
- // WaitBetterFeedback
- // NOTE: must be resident! We don't want a segment load at interrupt time
- //----------------------------------------------------------------------------------------
- #pragma push
- #pragma trace off
-
- #pragma segment ARes
-
- pascal void IncOurVBLCounter(
- #if qPowerPC
- VBLTaskPtr vblTaskPtr
- #endif
- )
- {
- const short theOffset = sizeof(long) * 2;
-
- #if qPowerPC
- // if we are running native PowerPC, the runtime architecture passes us a pointer to our
- // VBLTask as a parameter
- QElemWithA5AndCounterPtr qElemPtr = (QElemWithA5AndCounterPtr)((long)vblTaskPtr - theOffset);
- #else
- // if we are 680X0, we have to grab the VBLTask pointer from A0, using GetParmBlockPtr
- QElemWithA5AndCounterPtr qElemPtr = (QElemWithA5AndCounterPtr)(GetParmBlockPtr() - theOffset);
- #endif
-
- gOurVBLTask.OldA5 = SetA5(qElemPtr->A5);
- gOurVBLTask.q.vblCount = 1; // reprime the pump
- gCounter++; // increment our counter
- SetA5(gOurVBLTask.OldA5);
- }
- #pragma pop
-
- //----------------------------------------------------------------------------------------
- // GetAVideoSlot - Return the video slot associated with the view's port
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- short GetAVideoSlot(TView* aView)
- {
- TWindow* aWindow;
- DefVideoRec aDefVideoRec;
- GDHandle aGDHandle;
- CRect aRect;
- AuxDCEHandle anAuxDCEHandle;
-
- aWindow = aView->GetWindow();
- if (aWindow == NULL) {
- GetVideoDefault(&aDefVideoRec);
- return aDefVideoRec.sdSlot;
- }
- else {
- aGDHandle = aWindow->GetMaxIntersectedDevice(aRect);
- anAuxDCEHandle = (AuxDCEHandle)GetDCtlEntry((*aGDHandle)->gdRefNum);
- return (*anAuxDCEHandle)->dCtlSlot;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // InstallOurVBL - Install a VBL task to increment a counter
- // Used by TShapeCommand's TrackFeedback method
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void InstallOurVBL(TView* aView)
- {
- gCounter = 0;
- gOurVBLTask.q.qType = vType;
- gOurVBLTask.q.vblAddr = NewVBLProc(StripLong(IncOurVBLCounter));
- FailNIL(gOurVBLTask.q.vblAddr);
- gOurVBLTask.q.vblCount = 1;
- gOurVBLTask.q.vblPhase = 0;
- gOurVBLTask.A5 = SetCurrentA5(); // make the A5 world available to the VBL task
-
- // Install the VBL task
- if (TrapExists(_SlotVInstall)) {
- gSlot = GetAVideoSlot(aView);
- FailOSErr(SlotVInstall((QElemPtr) & gOurVBLTask.q, gSlot));
- }
- else
- FailOSErr(VInstall((QElemPtr) & gOurVBLTask.q));
- }
-
- //----------------------------------------------------------------------------------------
- // RemoveOurVBL - Remove the VBL task we installed
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void RemoveOurVBL()
- {
- if (TrapExists(_SlotVRemove))
- FailOSErr(SlotVRemove((QElemPtr) & gOurVBLTask.q, gSlot));
- else
- FailOSErr(VRemove((QElemPtr) & gOurVBLTask.q));
- }
-
- //========================================================================================
- // CLASS TBetterFeedbackCmd
- //========================================================================================
- #undef Inherited
- #define Inherited TTracker
-
- #pragma segment AInit
- MA_DEFINE_CLASS_M1(TBetterFeedbackCmd, Inherited);
-
- //----------------------------------------------------------------------------------------
- // TBetterFeedbackCmd Constructor
- //----------------------------------------------------------------------------------------
- #pragma segment AInit
-
- TBetterFeedbackCmd::TBetterFeedbackCmd()
- {
- fBetterFeedbackInstalled = !kInstall;
- fBetterFeedbackDesired = false;
- }
-
- //----------------------------------------------------------------------------------------
- // TBetterFeedbackCmd::IBetterFeedbackCmd:
- //----------------------------------------------------------------------------------------
- #pragma segment AInit
-
- void TBetterFeedbackCmd::IBetterFeedbackCmd(CommandNumber itsCommandNumber,
- TCommandHandler* itsContext,
- Boolean canUndo,
- Boolean causesChange,
- TObject* objectToNotify,
- TView* itsView,
- TScroller* itsScroller,
- VPoint itsMouse,
- Boolean betterFeedbackDesired)
- {
- this->ITracker(itsCommandNumber, itsContext, canUndo, causesChange, objectToNotify, itsView, itsScroller, itsMouse);
- fBetterFeedbackDesired = betterFeedbackDesired;
- }
-
- //----------------------------------------------------------------------------------------
- // TBetterFeedbackCmd::Free:
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void TBetterFeedbackCmd::Free() // Override
- {
- this->BetterFeedback(!kInstall);
- Inherited::Free();
- }
-
- //----------------------------------------------------------------------------------------
- // TBetterFeedbackCmd::TrackMouse:
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- TTracker* TBetterFeedbackCmd::TrackMouse(TrackPhase aTrackPhase,
- VPoint& /*anchorPoint*/,
- VPoint& /*previousPoint*/,
- VPoint& /*nextPoint*/,
- Boolean /*mouseDidMove*/) // Override
- {
- if (aTrackPhase == trackRelease)
- this->BetterFeedback(!kInstall);
- return this;
- }
-
- //----------------------------------------------------------------------------------------
- // TBetterFeedbackCmd::TrackFeedback:
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void TBetterFeedbackCmd::TrackFeedback(TrackPhase /*aTrackPhase*/,
- const VPoint& /*anchorPoint*/,
- const VPoint& /*previousPoint*/,
- const VPoint& /*nextPoint*/,
- Boolean mouseDidMove,
- Boolean turnItOn) // Override
- {
- if (mouseDidMove || !turnItOn)
- this->WaitBetterFeedback();
- }
-
- //----------------------------------------------------------------------------------------
- // TBetterFeedbackCmd::BetterFeedback:
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void TBetterFeedbackCmd::BetterFeedback(Boolean install)
- {
- if (fBetterFeedbackDesired == kBetterFeedbackDesired)
- {
- if ((install == kInstall) && (fBetterFeedbackInstalled == !kInstall))
- InstallOurVBL(fView);
- else if ((install == !kInstall) && (fBetterFeedbackInstalled == kInstall))
- RemoveOurVBL();
- fBetterFeedbackInstalled = install;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // TBetterFeedbackCmd::WaitBetterFeedback:
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void TBetterFeedbackCmd::WaitBetterFeedback()
- {
- if (fBetterFeedbackDesired == kBetterFeedbackDesired)
- {
- if (fBetterFeedbackInstalled == !kInstall)
- this->BetterFeedback(kInstall);
- long t = gCounter; // we'll wait til screen refresh
- while (t == gCounter) ; // let's hope this changes soon
- }
- }
-